Day6 的時候曾經使用過Union型別,今天就要正式認識Union型別。
Union的關鍵字是 |
,其用途是可以合併多個型別成一個型別,例如合併string和number為一個型別 string | number
。
Union的優點在於能夠避免將變數的型別指定為 any
而導致不必要的錯誤,例如下面範例希望宣告一個函式可以接收 string
、number
參數:
function print(input: any) {
if(typeof input === 'number' | typeof input === 'string'){
if(typeof input === 'number'){
input = input.toString();
}
console.log("Your input is " + input + ".");
} else {
throw new Error("Input is not string or number!");
}
}
print(5); // Your input is 5.
print(true); // Input is not string or number!
這個範例首先使用可允許任意型別的 any
模擬寫JavaScript可能會遇到的狀況,在寫JavaScript的時候為了避免 string
和 number
以外的型別,必須多寫一個判斷式,檢查出其他型別的 input
不過使用TypeScript時,如果不希望接收其他類型的型別,可以使用Union限制函式接收的參數只能是 string
和 number
:
function print(input: string|number) {
if(typeof input === 'number'){
input = input.toString();
}
console.log("Your input is " + input + ".");
}
print(5); // Your input is 5.
print(true); // Compile error
而這樣的好處除了能精簡程式碼、提高程式的可讀性,TypeScript Compiler也能在編譯期就找出錯誤,或者說在寫程式碼時就會提醒錯誤。
Union有個很常被使用的情境是結合多個 String literal型別,String literal簡單來說就是把文字當作型別,例如:
let person: "person" = "person"; // ok
person = "people"; // error
範例會出現錯誤是因為把 person
變數的型別指定給 "person"
,所以 person
變數的值只能是 "person"
。
不過,一般來說並不會這樣使用 String literal 型別,而是結合Union,將多個String literal型別結合成一個型別:
function getArrowKey(direction: "ArrowTop" | "ArrowRight" | "ArrowDown" | "ArrowLeft") {
let message = "";
switch(direction){
case "ArrowTop":
message = "You type top key";
break;
case "ArrowRight":
message = "You type right key";
break;
case "ArrowDown":
message = "You type down key";
break;
case "ArrowLeft":
message = "You type left key";
break;
default:
throw new Error("Type direction");
}
if(message){
console.log(message);
}
}
getDirection("top"); // You type top key.
為了增加Union type的可讀性,可以使用 type
關鍵字替自己創造的Union type命名,而自己額外替型別取的名字就稱為 type alias:
type Direction = "ArrowTop" | "ArrowRight" | "ArrowBottom" | "ArrowLeft";
function getArrowKey(direction: Direction) {
let message = "";
switch(direction) {
case "ArrowTop":
message = "You type top key";
break;
case "ArrowRight":
mesage = "You type right key";
break;
case "ArrowBottom":
message = "You type bottom key";
break;
case "ArrowLeft":
message = "You type left key";
break;
default:
throw new Error("Type direction!");
}
if(message) {
console.log(message);
}
}
參考資料
TypeScript for JavaScript Programmers
TypeScript Handbook
TypeScript Tutorial
String literal
那段範例會出現錯誤是因為把 person 變數的型別指定給 "person",所以 person 變數的值只能是 "person"。
怪怪的
底下的示範程式碼也怪怪的